package com.jhgsys.internal.incentive.service.impl;

import com.jhgsys.internal.common.exception.FebsException;
import com.jhgsys.internal.common.utils.BeanHelper;
import com.jhgsys.internal.incentive.dto.IncentiveQuotaApplyDto;
import com.jhgsys.internal.incentive.entity.*;
import com.jhgsys.internal.incentive.mapper.IncentiveQuotaApplyMapper;
import com.jhgsys.internal.incentive.service.IIncentiveQuotaApplyService;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.incentive.service.IIncentiveQuotaAuditRecordService;
import com.jhgsys.internal.incentive.service.IIncentiveQuotaConfigService;
import com.jhgsys.internal.incentive.service.IIncentiveRewardConfigService;
import com.jhgsys.internal.peccancy.service.IPeccancyInformationService;
import com.jhgsys.internal.system.entity.Tenant;
import com.jhgsys.internal.system.service.ITenantService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 *  Service实现
 *
 * @author zhangwei
 * @date 2024-09-03 13:16:21
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class IncentiveQuotaApplyServiceImpl extends ServiceImpl<IncentiveQuotaApplyMapper, IncentiveQuotaApply> implements IIncentiveQuotaApplyService {

    @Autowired
    private IIncentiveQuotaConfigService incentiveQuotaConfigService;

    @Autowired
    private IIncentiveQuotaAuditRecordService incentiveQuotaAuditRecordService;

    @Autowired
    private IIncentiveRewardConfigService incentiveRewardConfigService;

    @Autowired
    private IPeccancyInformationService peccancyInformationService;

    @Autowired
    private ITenantService tenantService;

    /**
     * 查询（分页）
     * @author zhangwei
     * @date 2024-09-03 13:16:21
     * @param request QueryRequest
     * @param incentiveQuotaApply incentiveQuotaApply
     * @return IPage<IncentiveQuotaApply>
    */
    @Override
    public IPage<IncentiveQuotaApply> findIncentiveQuotaApplyPage(QueryRequest request, IncentiveQuotaApply incentiveQuotaApply) {
        LambdaQueryWrapper<IncentiveQuotaApply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IncentiveQuotaApply::getDeletedFlg, 0);
        // TODO 设置查询条件
        if(StringUtils.isNotBlank(incentiveQuotaApply.getTenantId())){
            queryWrapper.eq(IncentiveQuotaApply::getTenantId,incentiveQuotaApply.getTenantId());
        }
        if(StringUtils.isNotBlank(incentiveQuotaApply.getUserId())){
            queryWrapper.eq(IncentiveQuotaApply::getUserId,incentiveQuotaApply.getUserId());
        }
        if(StringUtils.isNotBlank(incentiveQuotaApply.getQuotaApplyNo())){
            queryWrapper.like(IncentiveQuotaApply::getQuotaApplyNo,incentiveQuotaApply.getQuotaApplyNo());
        }
        if(null != incentiveQuotaApply.getYear()){
            queryWrapper.eq(IncentiveQuotaApply::getYear,incentiveQuotaApply.getYear());
        }
        if(StringUtils.isNotBlank(incentiveQuotaApply.getRealName())){
            queryWrapper.like(IncentiveQuotaApply::getRealName,incentiveQuotaApply.getRealName());
        }
        if(StringUtils.isNotBlank(incentiveQuotaApply.getStatus())){
            queryWrapper.eq(IncentiveQuotaApply::getStatus,incentiveQuotaApply.getStatus());
        }

        Page<IncentiveQuotaApply> page = new Page<>(request.getPageNum(), request.getPageSize());
        FebsUtil.pageWrapper(page, request);
        return this.page(page, queryWrapper);
    }

    /**
     * 查询（所有）
     * @author zhangwei
     * @date 2024-09-03 13:16:21
     * @param incentiveQuotaApply incentiveQuotaApply
     * @return List<IncentiveQuotaApply>
     */
    @Override
    public List<IncentiveQuotaApply> findIncentiveQuotaApplyList(IncentiveQuotaApply incentiveQuotaApply) {
	    LambdaQueryWrapper<IncentiveQuotaApply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(IncentiveQuotaApply::getDeletedFlg, 0);
		// TODO 设置查询条件
        if(StringUtils.isNotBlank(incentiveQuotaApply.getTenantId())){
            queryWrapper.eq(IncentiveQuotaApply::getTenantId, incentiveQuotaApply.getTenantId());
        }
        if(ObjectUtils.isNotEmpty(incentiveQuotaApply.getYear())){
            queryWrapper.eq(IncentiveQuotaApply::getYear, incentiveQuotaApply.getYear());
        }
        if(StringUtils.isNotBlank(incentiveQuotaApply.getStatus())){
            queryWrapper.eq(IncentiveQuotaApply::getStatus, incentiveQuotaApply.getStatus());
        }
		return this.baseMapper.selectList(queryWrapper);
    }

    /**
    * 根据ID查询
    * @author zhangwei
    * @date 2024-09-03 13:16:21
    * @param id
    * @return IncentiveQuotaApply
    */
    @Override
    public IncentiveQuotaApplyDto findIncentiveQuotaApplyById(String id){
        IncentiveQuotaApply incentiveQuotaApply = this.baseMapper.selectById(id);
        IncentiveQuotaConfig incentiveQuotaConfig = incentiveQuotaConfigService.findIncentiveQuotaConfigByUserId(incentiveQuotaApply.getUserId());
        IncentiveQuotaApplyDto incentiveQuotaApplyDto = BeanHelper.copyProperties(incentiveQuotaApply,IncentiveQuotaApplyDto.class);
        if(incentiveQuotaConfig != null){
            IncentiveRewardConfig incentiveRewardConfig = incentiveRewardConfigService.findIncentiveRewardConfigByTenantId(incentiveQuotaApply.getTenantId());
            Map<String,Object> map = peccancyInformationService.countPeccancyByInvoiceUserId(incentiveQuotaApplyDto.getUserId());
            //总罚款
            BigDecimal amoutCount = new BigDecimal(map.get("amountCount").toString());
            //总扣分
            BigDecimal scoreCount = new BigDecimal(map.get("scoreCount").toString());
            //罚款奖金比例
            BigDecimal penaltyBonusRatio = incentiveQuotaConfig.getPenaltyBonusRatio();
            //积分金额比例
            BigDecimal scoreAmountRatio = incentiveRewardConfig.getScoreAmountRatio();
            //计算罚款、积分所得额度
            BigDecimal calQuota = amoutCount.multiply(penaltyBonusRatio).add(scoreCount.multiply(scoreAmountRatio));
            //申请额度
            BigDecimal applyQuota = incentiveQuotaApply.getApplyQuota();
            //基础设置额度
            BigDecimal baseQuota = incentiveQuotaConfig.getTotalQuota();
            //上涨额度
            BigDecimal riseQuota = applyQuota.subtract(baseQuota);
            if(calQuota.compareTo(riseQuota) == -1){
                incentiveQuotaApplyDto.setFactQuota(applyQuota);
            }else if(calQuota.compareTo(riseQuota) == 1){
                incentiveQuotaApplyDto.setFactQuota(baseQuota.add(calQuota));
            }else{
                incentiveQuotaApplyDto.setFactQuota(applyQuota);
            }
            incentiveQuotaApplyDto.setTotalQuota(incentiveQuotaConfig.getTotalQuota());
            incentiveQuotaApplyDto.setRewardedQuota(incentiveQuotaConfig.getRewardedQuota());
            incentiveQuotaApplyDto.setRemindedQuota(incentiveQuotaConfig.getTotalQuota().subtract(incentiveQuotaConfig.getRewardedQuota()));
            incentiveQuotaApplyDto.setFineCalQuota(calQuota);
        }else{
            incentiveQuotaApplyDto.setTotalQuota(BigDecimal.valueOf(0));
            incentiveQuotaApplyDto.setRewardedQuota(BigDecimal.valueOf(0));
            incentiveQuotaApplyDto.setRemindedQuota(BigDecimal.valueOf(0));
            incentiveQuotaApplyDto.setFactQuota(incentiveQuotaApply.getApplyQuota());
            incentiveQuotaApplyDto.setFineCalQuota(BigDecimal.valueOf(0));
        }
        return incentiveQuotaApplyDto;
    }

    /**
     * 新增
     * @author zhangwei
     * @date 2024-09-03 13:16:21
     * @param incentiveQuotaApply incentiveQuotaApply
     */
    @Override
    @Transactional
    public void createIncentiveQuotaApply(IncentiveQuotaApply incentiveQuotaApply) throws FebsException{
        incentiveQuotaApply.setCreatedTime(new Date());
        incentiveQuotaApply.setYear(Calendar.getInstance().get(Calendar.YEAR));
        incentiveQuotaApply.setDeletedFlg("0");
        incentiveQuotaApply.setQuotaApplyNo(this.createQuotaApplyNo(incentiveQuotaApply.getTenantId()));
        incentiveQuotaApply.setStatus("2");
        this.save(incentiveQuotaApply);
    }

    /**
     * 修改
     * @author zhangwei
     * @date 2024-09-03 13:16:21
     * @param incentiveQuotaApply incentiveQuotaApply
     */
    @Override
    @Transactional
    public void updateIncentiveQuotaApply(IncentiveQuotaApply incentiveQuotaApply) {
        incentiveQuotaApply.setUpdatedTime(new Date());
        this.saveOrUpdate(incentiveQuotaApply);
    }

    /**
     * 审核
     *
     * @param incentiveQuotaApplyDto incentiveQuotaApplyDto
     * @author zhangwei
     * @date 2024-09-03 13:16:21
     */
    @Override
    public void auditIncentiveQuotaApply(IncentiveQuotaApplyDto incentiveQuotaApplyDto) {
        IncentiveQuotaApply incentiveQuotaApply = BeanHelper.copyProperties(incentiveQuotaApplyDto, IncentiveQuotaApply.class);
        if(StringUtils.isNotBlank(incentiveQuotaApplyDto.getAuditStatus())){
            switch (incentiveQuotaApplyDto.getAuditStatus()){
                case "1":
                    incentiveQuotaApply.setStatus("3");
                    IncentiveQuotaConfig incentiveQuotaConfig = incentiveQuotaConfigService.findIncentiveQuotaConfigByUserId(incentiveQuotaApply.getUserId());
                    incentiveQuotaConfig.setTotalQuota(incentiveQuotaApplyDto.getFactQuota());
                    incentiveQuotaConfigService.saveOrUpdate(incentiveQuotaConfig);
                    break;
                case "0":incentiveQuotaApply.setStatus("4");break;
            }
        }
        incentiveQuotaApply.setAuditDate(new Date());
        this.saveOrUpdate(incentiveQuotaApply);
        //写入审核记录表
        IncentiveQuotaAuditRecord record = new IncentiveQuotaAuditRecord();
        record.setTenantId(incentiveQuotaApplyDto.getTenantId());
        record.setQuotaApplyId(incentiveQuotaApply.getQuotaApplyId());
        record.setAuditUserId(incentiveQuotaApplyDto.getAuditUserId());
        record.setAuditRealName(incentiveQuotaApplyDto.getAuditRealName());
        record.setAuditResult(incentiveQuotaApplyDto.getAuditStatus());
        record.setAuditReason(incentiveQuotaApplyDto.getAuditRemark());
        record.setCreatedBy(incentiveQuotaApplyDto.getAuditUserId());
        record.setCreatedTime(new Date());
        record.setDeletedFlg("0");
        incentiveQuotaAuditRecordService.saveOrUpdate(record);
    }

    /**
     * 逻辑删除
     * @author zhangwei
     * @date 2024-09-03 13:16:21
     * @param incentiveQuotaApply incentiveQuotaApply
     * @param incentiveQuotaApplyIds incentiveQuotaApplyIds
     */
    @Override
    @Transactional
    public void deleteIncentiveQuotaApply(IncentiveQuotaApply incentiveQuotaApply,String incentiveQuotaApplyIds) {
        List<String> list = Arrays.asList(incentiveQuotaApplyIds.split(StringPool.COMMA));
        this.baseMapper.update(incentiveQuotaApply,new LambdaQueryWrapper<IncentiveQuotaApply>().in(IncentiveQuotaApply::getQuotaApplyId,list));
	}

    /**
    * 物理删除
    * @author zhangwei
    * @date 2024-09-03 13:16:21
    * @param incentiveQuotaApplyIds incentiveQuotaApplyIds
    */
    @Override
    @Transactional
    public void physicallyDeleteIncentiveQuotaApply(String incentiveQuotaApplyIds) {
        List<String> list = Arrays.asList(incentiveQuotaApplyIds.split(StringPool.COMMA));
        LambdaQueryWrapper<IncentiveQuotaApply> wapper = new LambdaQueryWrapper<>();
        wapper.in(IncentiveQuotaApply::getQuotaApplyId,list);
        this.remove(wapper);
    }

    /**
     * 生成编号 年+公司编码+序列号（5位）
     *
     * @param tenantId 公司ID
     * @author zhangwei
     * @date 2024-09-03 16:45:01
     */
    @Override
    public String createQuotaApplyNo(String tenantId) throws FebsException {
        String applyNo = "";
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Tenant tenant = tenantService.getById(tenantId);
        if(null == tenant || StringUtils.isBlank(tenant.getTenantCode())){
            throw new FebsException("编号生成异常");
        }
        String tenantCode = tenant.getTenantCode();
        LambdaQueryWrapper<IncentiveQuotaApply> queryWrapper = new LambdaQueryWrapper<IncentiveQuotaApply>();
        queryWrapper.eq(IncentiveQuotaApply::getDeletedFlg,0);
        queryWrapper.eq(IncentiveQuotaApply::getTenantId,tenantId);
        queryWrapper.apply("DATE_FORMAT(created_time,'%Y') = DATE_FORMAT(NOW(),'%Y')");
        List<IncentiveQuotaApply> applyList = this.baseMapper.selectList(queryWrapper);
        Integer length = applyList.size();
        String yearStr = String.valueOf(calendar.get(Calendar.YEAR));
        String sequencePrefix = "";
        if (length < 99999) {
            sequencePrefix = String.format("%5d", length + 1).replace(" ", "0");
        } else {
            sequencePrefix = String.format("%8d", length + 1).replace(" ", "0");
        }
        applyNo = yearStr + tenantCode + sequencePrefix;
        return applyNo;
    }
}
